﻿namespace Deppton.Repositories.Filesystem.Tests
{
    using System.IO;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Moq;
    using Deppton.Model.Xml;
    using System.Xml.Linq;
    using System.Globalization;
    using Deppton.Model;

    /// <summary>
    /// This is a test class for FilesystemSurveysRepositoryTest and is intended
    /// to contain all FilesystemSurveysRepositoryTest Unit Tests
    /// </summary>
    [TestClass()]
    public class FilesystemSurveysRepositoryTest
    {
        public FilesystemSurveysRepositoryTest()
        {
            this.TestPath = Path.Combine(Directory.GetCurrentDirectory(), "teststorage");
        }

        [TestInitialize]
        public void Initialize()
        {
            this.EnsureEmptyDirectory(this.TestPath);
        }

        public string TestPath
        {
            get;
            set;
        }

        [TestMethod]
        [DeploymentItem("assignations1.xml")]
        public void ShouldFindAssignedSurveysForUser()
        {
            AddSampleFile("assignations1.xml", "assignations.xml");

            var handler = new FilesystemSurveysAssignationsHandler(this.TestPath);

            var result = handler.FindAssignedSurveysForUser("myuser");

            Assert.IsNotNull(result);
            var list = result.ToList();
            Assert.AreEqual(1, result.Count);
            Assert.AreEqual("survey1", list[0]);
        }

        [TestMethod()]
        [DeploymentItem("survey1.xml")]
        public void ShouldReturnPendingSurveysForUser()
        {
            var assignationsHandlerMock = new Mock<ISurveysAssignationsHandler>();

            var username = "myuser";

            assignationsHandlerMock
                .Setup(h => h.FindAssignedSurveysForUser(username))
                .Returns(new[] { "survey1" }.ToList());

            AddSampleFile("survey1.xml");

            var repository = new FilesystemSurveysRepository(this.TestPath, assignationsHandlerMock.Object);

            var result = repository.FindPendingSurveysByUser(username);

            Assert.IsNotNull(result);
            Assert.AreEqual(1, result.Count);
            Assert.AreEqual("survey1", result.ToList()[0].Id);
            Assert.AreEqual("sd1", result.ToList()[0].SurveyDefinitionId);

            assignationsHandlerMock.Verify();
        }

        [TestMethod()]
        [DeploymentItem("survey1.xml")]
        [DeploymentItem("survey2.xml")]
        public void ShouldReturnsOnlyPendingSurveysForUser()
        {
            var assignationsHandlerMock = new Mock<ISurveysAssignationsHandler>();

            var username = "myuser";

            assignationsHandlerMock
                .Setup(h => h.FindAssignedSurveysForUser(username))
                .Returns(new[] { "survey1", "survey2" }.ToList());

            AddSampleFile("survey1.xml");
            AddSampleFile("survey2.xml");

            var repository = new FilesystemSurveysRepository(this.TestPath, assignationsHandlerMock.Object);

            var result = repository.FindPendingSurveysByUser(username);

            Assert.IsNotNull(result);
            Assert.AreEqual(1, result.Count);
            Assert.AreEqual("survey1", result.ToList()[0].Id);
            Assert.AreEqual("sd1", result.ToList()[0].SurveyDefinitionId);

            assignationsHandlerMock.VerifyAll();
        }

        [TestMethod()]
        [DeploymentItem("survey1.xml")]
        public void ShouldSaveSurvey()
        {
            var assignationsHandlerMock = new Mock<ISurveysAssignationsHandler>();

            var outputPath = Path.Combine(this.TestPath, "output");
            EnsureEmptyDirectory(outputPath);

            var repository = new FilesystemSurveysRepository(
                outputPath,
                assignationsHandlerMock.Object);
            var survey = SurveyXmlHelper.ReadFromElement(
                XDocument.Load(Path.Combine(Directory.GetCurrentDirectory(), "survey1.xml")).Root);

            repository.Save(survey);

            assignationsHandlerMock.VerifyAll();
            var savedSurveyPath = Path.Combine(outputPath, "survey1.xml");
            Assert.IsTrue(File.Exists(savedSurveyPath));
            var savedSurvey = SurveyXmlHelper.ReadFromElement(XDocument.Load(savedSurveyPath).Root);

            Assert.IsTrue(survey.Equals(savedSurvey));
        }

        private void AddSampleFile(string filename)
        {
            File.Copy(
                Path.Combine(Directory.GetCurrentDirectory(), filename),
                Path.Combine(this.TestPath, filename));
        }

        private void AddSampleFile(string filename, string targetFilename)
        {
            File.Copy(Path.Combine(
                Directory.GetCurrentDirectory(), filename),
                Path.Combine(this.TestPath, targetFilename));
        }

        private void EnsureEmptyDirectory(string path)
        {
            if (Directory.Exists(path))
            {
                Directory.Delete(path, true);
            }

            Directory.CreateDirectory(path);
        }
    }
}
